---
title: "Mutation"
description: "Imperative and mutative programming capabilities in ReScript"
canonical: "/docs/manual/mutation"
section: "Language Features"
order: 17
---

# Mutation

ReScript has great traditional imperative & mutative programming capabilities. You should use these features sparingly, but sometimes they allow your code to be more performant and written in a more familiar pattern.

## Mutate Let-binding

Let-bindings are immutable, but you can wrap it with a `ref`, exposed as a record with a single mutable field in the standard library:

<CodeTab labels={["ReScript", "JS Output"]}>

```res prelude
let myValue = ref(5)
```

```js
var myValue = {
  contents: 5,
};
```

</CodeTab>

## Usage

You can get the actual value of a `ref` box through accessing its `contents` field:

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
let five = myValue.contents // 5
```

```js
var five = myValue.contents;
```

</CodeTab>

Assign a new value to `myValue` like so:

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
myValue.contents = 6
```

```js
myValue.contents = 6;
```

</CodeTab>

We provide a syntax sugar for this:

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
myValue := 6
```

```js
myValue.contents = 6;
```

</CodeTab>

Note the `mut` at binding; see [let binding](./let-binding.mdx)!. While a tuple is always

**Note**: you might see in the JS output tabs above that `ref` allocates an object. Worry not; local, non-exported `ref`s allocations are optimized away.

## Tip & Tricks

Before reaching for `ref`, know that you can achieve lightweight, local "mutations" through [overriding let bindings](./let-binding.mdx#binding-shadowing).
